﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Interactivity;
using System.Windows.Data;
using System.ComponentModel;

namespace G
{
    /// <summary>
    /// 使用本类可以方便的将DependencyObject属性的变化通过事件的方式反馈给使用者
    /// </summary>
    public class PropertyValueChangedNotify : Behavior<DependencyObject>, IValueConverter
    {
        public static PropertyValueChangedNotify Create(string path, DependencyObject d)
        {
            PropertyValueChangedNotify p = new PropertyValueChangedNotify();
            p.Path = new PropertyPath(path);
            var behaviors = System.Windows.Interactivity.Interaction.GetBehaviors(d);
            behaviors.Add(p);
            return p;
        }

        public static readonly DependencyProperty PathProperty = DependencyProperty.Register("Path", typeof(PropertyPath), typeof(PropertyValueChangedNotify), new PropertyMetadata(null, new PropertyChangedCallback((e, s) =>
        {
            PropertyValueChangedNotify p = e as PropertyValueChangedNotify;
            p.SetBinding();
        })));

        [TypeConverter(typeof(PropertyPathConverter))]
        public PropertyPath Path
        {
            get
            {
                return (PropertyPath)this.GetValue(PathProperty);
            }
            set
            {
                this.SetValue(PathProperty, value);
            }
        }
        TextBlock t = new TextBlock();
        protected override void OnAttached()
        {
            base.OnAttached();
            SetBinding();
        }
        private void SetBinding()
        {
            Binding bingding = new Binding
            {
                Path = this.Path,
                Converter = this,
                Source = this.AssociatedObject
            };
            this.t.SetBinding(TextBlock.TagProperty, bingding);
        }

        public event PropertyValueChangedHandle PropertyValueChanged;
        object oldValue;
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (PropertyValueChanged != null)
            {
                this.PropertyValueChanged(this.AssociatedObject, new PropertyValueChangedEventArgs(oldValue, value));
                this.oldValue = value;
            }
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public delegate void PropertyValueChangedHandle(DependencyObject d, PropertyValueChangedEventArgs e);

    public class PropertyValueChangedEventArgs : EventArgs
    {
        public object OldValue { get; private set; }
        public object NewValue { get; private set; }
        internal PropertyValueChangedEventArgs(object oldValue, object newValue)
        {
            this.OldValue = oldValue;
            this.NewValue = newValue;
        }
    }
}
